#include "base_server.cpp"
#include <sys/time.h> 

#define MAXN 16384
#define MAXLINE 10

int my_connect(char* ip, int port);
long long getTime();
void diffTime(long long beginTime, long long endTime);

int main(int argc, char **argv){
    int i, j, fd, nchildren, nloops, nbytes;
    pid_t pid;
    ssize_t n;
    char request[MAXLINE], reply[MAXN];
    char *ip;
    int port;
    struct sockaddr_in serv_addr;

    if(argc != 6){
        error_func("usage:client <hostname or ipaddr> <port> <children> <loops/child> <bytes/request>");
    }

    ip = argv[1];
    port = atoi(argv[2]);
    nchildren = atoi(argv[3]);
    nloops = atoi(argv[4]);
    nbytes = atoi(argv[5]);

    
    long long beginTime = getTime();
    for(i = 0; i< nchildren; i++){
        if((pid = fork()) == 0){
            //child
            for(j = 0; j < nloops; j++){
                int sockfd;
                sockfd = my_connect(ip, port);

                write(sockfd, "hello", 100);
                int n = 0;
                char buffer[256];
                n = read(sockfd, buffer, 255);
                
                close(sockfd);
                printf("child %d-%d done\n", i, j);
            }
            
            exit(0);
        }
    }

    while(wait(NULL) > 0){

    }

    long long endTime = getTime();
    diffTime(beginTime, endTime);
    
    exit(0);
}

long long getTime(){
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
}

void diffTime(long long beginTime, long long endTime){
    printf("begin at : %lld\n", beginTime);
    printf("end at : %lld\n", endTime);

    long long diffTime = endTime - beginTime;
    int s = diffTime/1000000;
    int ms = (diffTime - s * 1000000) / 1000;
    int us = (diffTime - s * 1000000 - ms * 1000);
    printf("diff at : %ds %dms %dus\n", s, ms, us);
}

int my_connect(char* ip, int port){
    struct sockaddr_in serv_addr;
    //创建socket
    int sockfd;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        error_func("create socket失败", sockfd);
    }

    //准备connect
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(ip);
    serv_addr.sin_port = htons(port);
    if(::connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0){
        error_func("connect socket失败");
    }

    return sockfd;
}